//package work.timejay.utils.sqlEncrypt;
//
//import com.alibaba.druid.filter.FilterEventAdapter;
//import com.alibaba.druid.proxy.jdbc.JdbcParameter;
//import com.alibaba.druid.proxy.jdbc.PreparedStatementProxy;
//import com.alibaba.druid.proxy.jdbc.StatementProxy;
//import com.alibaba.druid.sql.SQLUtils;
//import com.alibaba.druid.sql.ast.SQLExpr;
//import com.alibaba.druid.sql.ast.SQLStatement;
//import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlInsertStatement;
//import com.alibaba.druid.util.JdbcConstants;
//
//import com.mysql.cj.ClientPreparedQuery;
//import com.mysql.cj.ClientPreparedQueryBindValue;
//import com.mysql.cj.ClientPreparedQueryBindings;
//import com.mysql.cj.jdbc.ClientPreparedStatement;
//import lombok.SneakyThrows;
//import lombok.extern.slf4j.Slf4j;
//import org.springframework.stereotype.Component;
//import org.springframework.util.CollectionUtils;
//
//import java.nio.charset.StandardCharsets;
//import java.sql.SQLException;
//import java.util.List;
//
///**
// * @className:CustomSqlFileter.java
// * @author:王文杰
// * @version:1.0.0
// * @description:sql 拦截器
// * @createTime 2024年01月29日 10:50:00
// */
//@Slf4j
//@Component
//public class CustomSqlFilter extends FilterEventAdapter {
//    @Override
//    protected void statementExecuteUpdateBefore(StatementProxy statement, String sql) {
//        super.statementExecuteUpdateBefore(statement, sql);
//        log.info("11111111111111111");
//    }
//
//    @Override
//    protected void statementExecuteQueryBefore(StatementProxy statement, String sql) {
//        super.statementExecuteQueryBefore(statement, sql);
//        log.info("222222222222222222");
//    }
//
//    @Override
//    protected void statementExecuteBatchBefore(StatementProxy statement) {
//        super.statementExecuteBatchBefore(statement);
//        log.info("3333333333333333333333333");
//    }
//
//    @SneakyThrows
//    @Override
//    protected void statementExecuteBefore(StatementProxy statement, String sql) {
//        super.statementExecuteBefore(statement, sql);
//        PreparedStatementProxy preparedStatement = (PreparedStatementProxy) statement;
//        String batchSql = preparedStatement.getSql();
//        List<SQLStatement> sqlStatements = SQLUtils.parseStatements(batchSql, JdbcConstants.MYSQL);
//        SQLStatement sqlStatement = sqlStatements.get(0) != null ? sqlStatements.get(0) : null;
//        if (sqlStatement != null) {
//            // 使用访问器获取关键结构
//            //MySqlSchemaStatVisitor visitor = new MySqlSchemaStatVisitor();
//            //SMxMySqlSchemaStatVisitor visitor = new SMxMySqlSchemaStatVisitor();
//            //sqlStatement.accept(visitor);
//            if (sqlStatement instanceof MySqlInsertStatement) {
//                // Insert操作
//                //handleBatchInsert(batchSql, preparedStatement, (MySqlInsertStatement) sqlStatement);
//                handleInsert(statement,batchSql,preparedStatement,(MySqlInsertStatement) sqlStatement);
////            } else if (sqlStatement instanceof MySqlUpdateStatement) {
////                // Update操作
////                handleBatchUpdate(batchSql, preparedStatement, (MySqlUpdateStatement) sqlStatement, visitor);
////            }
//            }
//        }
//        log.info("44444444444444444444444");
//
//    }
//
//    /**
//     * 处理插入操作
//     * @param statement
//     * @param sql
//     * @param preparedStatement
//     * @param sqlStatement
//     * @throws SQLException
//     */
//    private void handleInsert(StatementProxy statement, String sql, PreparedStatementProxy preparedStatement, MySqlInsertStatement sqlStatement) throws SQLException {
//        MySqlInsertStatement insertStatement = sqlStatement;
//        String tableName = insertStatement.getTableName().getSimpleName();
//        List<SQLExpr> columns = insertStatement.getColumns();
//        int paramIndex = -1; // 传入参数索引
//        for (SQLExpr column : columns) {
//            paramIndex++; // 无论是否匹配目标列都需要加1以保证参数索引正确
//            JdbcParameter parameter = statement.getParameter(paramIndex);
//            Object rawValueObj = parameter.getValue();
//            // 参数不为null并且匹配目标列则进行加密后替换加密后的参数,注意JDBC设置参数时从下标从1开始
//            if (rawValueObj != null && EncryptCommonUtils.isEncryptTable(tableName)) {
//                //String encValue = cryptoModule.encrypt(String.valueOf(rawValueObj));
//                String encValue = rawValueObj.toString();
//                preparedStatement.setString(paramIndex + 1, encValue);
//                log.info("===> [insert]命中目标列[{}]，入参值[{}]，加密后[{}], SQL: [{}]", column, rawValueObj, encValue, sql);
//            }
//        }
//    }
//
//    /**
//     * 处理批量插入操作
//     *
//     * @param sql
//     * @param preparedStatement
//     * @param sqlStatement
//     */
//    private void handleBatchInsert(String sql, PreparedStatementProxy preparedStatement, MySqlInsertStatement sqlStatement) {
//        ClientPreparedStatement rawObject = (ClientPreparedStatement) preparedStatement.getRawObject();
//        ClientPreparedQuery rawQuery = (ClientPreparedQuery) rawObject.getQuery();
//        List<Object> batchedArgs = rawQuery.getBatchedArgs();
//
//        MySqlInsertStatement insertStatement = sqlStatement;
//        String tableName = insertStatement.getTableName().getSimpleName();
//        List<SQLExpr> columns = insertStatement.getColumns();
//        int paramIndex = -1; // 传入参数索引
//        for (SQLExpr column : columns) {
//            paramIndex++; // 无论是否匹配目标列都需要加1以保证参数索引正确
//            if (EncryptCommonUtils.isEncryptTable(tableName)) {
//                if (!CollectionUtils.isEmpty(batchedArgs)) {
//                    for (int i = 0; i < batchedArgs.size(); i++) {
//                        ClientPreparedQueryBindings bindings = (ClientPreparedQueryBindings) batchedArgs.get(i);
//                        ClientPreparedQueryBindValue[] bindValues = bindings.getBindValues();
//                        ClientPreparedQueryBindValue bindValue = bindValues[paramIndex];
//                        if (bindValue.isSet() && !bindValue.isNull()) {
//                            byte[] byteValue = bindValue.getByteValue();
//                            String valStr = new String(byteValue);
//                            log.debug("原始参数: {}", valStr);
//                            if (valStr.startsWith("'") && valStr.endsWith("'")) {
//                                String origValue = valStr.substring(1, valStr.length() - 1);
//                                log.debug("原始值: {}", origValue);
//                                //String encValue = cryptoModule.encrypt(origValue);
//                                String encValue = origValue;
//                                log.debug("加密值: {}", encValue);
//                                bindValue.setByteValue(("'" + encValue + "'").getBytes(StandardCharsets.UTF_8));
//                                log.debug("===> [批量insert]命中目标列[{}]，入参值[{}]，加密后[{}], SQL: [{}]", column, origValue, encValue, sql);
//                            }
//                        }
//                    }
//                }
//            }
//        }
//    }
//}
